import gov.nih.mipav.model.structures.VOI;
import gov.nih.mipav.view.ViewUserInterface;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * This class is intended to manage all the region information. It's drawable
 * since its display as a window showing all the added regions and the actions
 * over them.
 * 
 * @author marco.zanger
 */
public class RegionManager extends ListModule implements Drawable, Dialogable,
    MethodRelated, ActionListener, ListSelectionListener {

  private static RegionManager theInstance;

  private Map<VOI, Region> map;

  private JDialog dialog;

  private RegionManager() {
    super(DefaultListSelectionModel.SINGLE_SELECTION);
    map = new HashMap<VOI, Region>();
  }

  public static RegionManager getInstance() {
    if (theInstance == null) {
      theInstance = new RegionManager();
    }
    return theInstance;
  }

  @Override
  public boolean needsToBeUpdated() {
    return true;
  }

  @Override
  protected void updateMe() {
  }

  @Override
  public Component drawContentPane() {
    JButton theButton = new JButton("RM");
    theButton.setActionCommand(Settings.REGION_MANAGER);
    theButton.addActionListener(this);
    return theButton;
  }

  @Override
  public void setEnable(boolean enable) {
  }

  @Override
  public void showDialog() {
    if (this.dialog == null) {
      ViewUserInterface mipavInterface = ViewUserInterface.getReference();
      this.dialog = new JDialog(mipavInterface.getMainFrame(), "Region Manager");
    }

    this.updateMe();

    if (!this.dialog.isVisible()) {
      JPanel thePanel = new JPanel();

      JList list = this.getList();
      JScrollPane scrollPane = new JScrollPane(list);
      scrollPane.setPreferredSize(new Dimension(300, 150));
      thePanel.add(scrollPane);

      JButton addRegionButton = new JButton("Add Region");
      addRegionButton.setActionCommand(Settings.ADD_REGION);
      addRegionButton.addActionListener(this);

      JButton removeRegionButton = new JButton("Remove Region");
      removeRegionButton.setActionCommand(Settings.REMOVE_REGION);
      removeRegionButton.addActionListener(this);

      JPanel buttonPane = new JPanel();
      buttonPane.setLayout(new FlowLayout());
      buttonPane.add(addRegionButton);
      buttonPane.add(removeRegionButton);

      this.dialog.getContentPane().setLayout(new BorderLayout(5, 5));
      this.dialog.getContentPane().add(thePanel, BorderLayout.CENTER);
      this.dialog.getContentPane().add(buttonPane, BorderLayout.SOUTH);

      this.dialog.pack();
      this.dialog.setResizable(false);

      this.dialog.setVisible(true);
    }

  }

  @Override
  public void updateProxy() {
    // TODO Auto-generated method stub

  }

  @Override
  public void actionPerformed(ActionEvent arg0) {
    if (arg0.getActionCommand().equals(Settings.REGION_MANAGER)) {
      this.showDialog();
    } else if (arg0.getActionCommand().equals(Settings.ADD_REGION)) {
      String regionName = JOptionPane.showInputDialog(this.dialog,
          Settings.ADD_REGION_MESSAGE, "<New Region>");
      if (regionName != null) {
        this.addRegion(regionName);
      }
    } else if (arg0.getActionCommand().equals(Settings.REMOVE_REGION)) {
      this.removeSelectedObjects();
    }
  }

  /**
   * Given a regions name it creates a new region in case there is no other
   * region with that name.
   * 
   * @param regionName
   */
  private void addRegion(String regionName) {
    if (this.regionExists(regionName)) {
      JOptionPane.showMessageDialog(this.dialog,
          Settings.REGION_ALREADY_EXISTS_ERROR_MESSAGE);
    } else {
      Region region = new Region(regionName);
      this.addObject(region);
    }
  }

  public boolean regionExists(String regionName) {
    Region tempRegion = new Region(regionName);
    return this.containsObject(tempRegion);
  }

  @Override
  public void valueChanged(ListSelectionEvent arg0) {
  }

  public int getVOIValue(String voiName) {
    return 0;
  }

  public ArrayList<Region> getRegions() {
    return new ArrayList<Region>();
  }

  /**
   * Returns the region for given VOI.
   * 
   * @param voi
   *          the voi, man!
   * @return the region where it belongs or null.
   */
  public Region getRegion(VOI voi) {
    Region region = this.map.get(voi);
    return region;
  }

  /**
   * When the double click is triggered upon a region it allows to change its
   * name.
   */
  protected void modifyObject() {
    String newName = JOptionPane.showInputDialog(this.dialog,
        Settings.ADD_REGION_MESSAGE, "<New name for oldie>");
    if (newName != null) {
      Region region = (Region) this.getFirstSelectedObject();
      if (this.regionExists(newName)) {
        JOptionPane.showMessageDialog(this.dialog,
            Settings.REGION_ALREADY_EXISTS_ERROR_MESSAGE);
      } else {
        region.setName(newName);
      }
    }
  }

  @Override
  protected void selectObject() {
  }
}
